﻿// Copyright (c) 2014 Converter Systems LLC

using ConverterSystems.ServiceModel;
using Opc.Ua;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Net;
using System.Net.Security;

namespace ConverterSystems.Workstation.Infrastructure
{
    /// <summary>
    /// An ApplicationConfiguration for communicating via OpcUa.
    /// </summary>
    [Export]
    public class UaConfiguration : ApplicationConfiguration
    {
        public UaConfiguration()
        {
            ApplicationName = "ConverterSystems.Workstation";
            ApplicationType = ApplicationType.Client;
            // storing the application certificate in the Windows certificate store "CurrentUser\My" [ aka "Personal" in certmgr ]
            // allows us to create the certificate without needing to run as administrator.
            SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier { StoreType = @"Windows", StorePath = @"CurrentUser\My", SubjectName = Utils.Format(@"CN={0}, DC={1}", ApplicationName, Dns.GetHostName()) }, TrustedPeerCertificates = new CertificateTrustList { StoreType = @"Windows", StorePath = @"CurrentUser\TrustedPeople", }, NonceLength = 32, AutoAcceptUntrustedCertificates = true };
            TransportConfigurations = new TransportConfigurationCollection();
            TransportQuotas = new TransportQuotas { OperationTimeout = 15000 }; // set 3 * sub.PublishingInterval * sub.KeepAliveCount
            ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 };
            TraceConfiguration = new TraceConfiguration { TraceMasks = Utils.TraceMasks.Error | Utils.TraceMasks.Information };
            TraceConfiguration.ApplySettings();
            Utils.SetTraceOutput(base.TraceConfiguration.TraceMasks != 0 ? Utils.TraceOutput.StdOutAndFile : Utils.TraceOutput.Off);
            Validate(base.ApplicationType);
            this.EnsureApplicationCertificate(); // creates an application certificate if one is not found in store.
            if (SecurityConfiguration.AutoAcceptUntrustedCertificates)
            {
                CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted); };
                // for https endpoints
                ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => { return (d == SslPolicyErrors.None) || (d == SslPolicyErrors.RemoteCertificateChainErrors); };
            }
        }
    }
}